package com.lzy.system.business.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzy.exception.BusException;
import com.lzy.system.business.common.SysBusEntityCommon;
import com.lzy.system.business.dto.SysBusEntityAddDTO;
import com.lzy.system.business.dto.SysBusEntityFieldAddDTO;
import com.lzy.system.business.dto.SysBusEntityFieldUpdateDTO;
import com.lzy.system.business.dto.SysBusEntityUpdateDTO;
import com.lzy.system.business.dto.convert.SysBusEntityConvert;
import com.lzy.system.business.dto.convert.SysBusEntityFieldConvert;
import com.lzy.system.business.entity.SysBus;
import com.lzy.system.business.entity.SysBusEntity;
import com.lzy.system.business.entity.SysBusEntityField;
import com.lzy.system.business.mapper.SysBusEntityFieldMapper;
import com.lzy.system.business.mapper.SysBusEntityMapper;
import com.lzy.system.business.mapper.SysBusMapper;
import com.lzy.system.business.service.ISysBusEntityService;
import com.lzy.utils.DbUtilsBySession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.context.Context;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 存储表 服务实现类
 * </p>
 *
 * @author lcc
 * @since 2024-01-21
 */
@Service
@Slf4j
public class SysBusEntityServiceImpl extends ServiceImpl<SysBusEntityMapper, SysBusEntity> implements ISysBusEntityService {

    @Value("${platform.db}")
    private String db;
    private SysBusMapper sysBusMapper;
    private SysBusEntityFieldMapper sysBusEntityFieldMapper;
    private SysBusEntityConvert sysBusEntityConvert;
    private SysBusEntityFieldConvert sysBusEntityFieldConvert;

    private DbUtilsBySession dbUtilsBySession;

    @Autowired
    public SysBusEntityServiceImpl(SysBusEntityFieldMapper sysBusEntityFieldMapper, SysBusEntityConvert sysBusEntityConvert, SysBusEntityFieldConvert sysBusEntityFieldConvert, SysBusMapper sysBusMapper, DbUtilsBySession dbUtilsBySession) {
        this.sysBusEntityFieldMapper = sysBusEntityFieldMapper;
        this.sysBusEntityConvert = sysBusEntityConvert;
        this.sysBusEntityFieldConvert = sysBusEntityFieldConvert;
        this.sysBusMapper = sysBusMapper;
        this.dbUtilsBySession = dbUtilsBySession;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveEntity(SysBusEntityAddDTO sysBusEntityAddDTO) throws BusException {
        SysBus sysBus = sysBusMapper.selectById(sysBusEntityAddDTO.getBus_id());
        if (sysBus == null) {
            throw new BusException("业务模型不存在");
        }
        //检查名字是否重复
        List list_entity = this.list(new QueryWrapper() {{
            eq("bus_id", sysBusEntityAddDTO.getBus_id());
            eq("name", sysBusEntityAddDTO.getName());
        }});
        if (list_entity.size() > 0) {
            throw new BusException("存储模型已经存在请修改名字");
        }
        SysBusEntity sysBusEntity = sysBusEntityConvert.addDtoToEntity(sysBusEntityAddDTO);
        //保存存储模型
        this.save(sysBusEntity);
        //保存存储模型字段
        List<SysBusEntityFieldAddDTO> fieldList = sysBusEntityAddDTO.getFieldList();
        int index = 1;
        for (SysBusEntityFieldAddDTO fieldAddDTO : fieldList) {
            if (SysBusEntityCommon.exclude.contains(fieldAddDTO.getF_name())) {
                throw new BusException("字段名不能是" + SysBusEntityCommon.exclude.toString());
            }
            //检查字段是否同名
            SysBusEntityField sysBusEntityField = sysBusEntityFieldConvert.addDtoToEntity(fieldAddDTO);
            sysBusEntityField.setOrder_index(index);
            List<SysBusEntityField> sysBusEntityFields = sysBusEntityFieldMapper.selectList(new QueryWrapper<>() {{
                eq("entity_id", sysBusEntity.getId());
                eq("f_name", sysBusEntityField.getF_name());
            }});
            if (sysBusEntityFields.size() > 0) {
                throw new BusException(StrUtil.format("字段({}-{})已经存在请修改名字", sysBusEntityField.getF_title(), sysBusEntityField.getF_name()));
            }
            sysBusEntityField.setEntity_id(sysBusEntity.getId());
            sysBusEntityFieldMapper.insert(sysBusEntityField);
            index++;
        }
        //准备数据 使用context
        Context context = new Context();
        //添加基本类型
        context.setVariable("table", sysBusEntityAddDTO);
        context.setVariable("busName", sysBus.getBus_name().replaceAll("-", "_"));

        String dir = "create_table";
        String out = SysBusEntityCommon.getSqlTemplate(context, db, dir);
        try {
            dbUtilsBySession.excuteSql(out, this.getSqlSessionFactory().openSession());
        } catch (Exception e) {
            log.error("创建存储模型失败", e);
            throw new BusException("创建存储模型失败");
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEntity(SysBusEntityUpdateDTO sysBusEntityUpdateDTO) throws BusException {
        //查询所有的字段
        SysBusEntityField last_field = sysBusEntityFieldMapper.selectOne(new QueryWrapper<>() {{
            eq("entity_id", sysBusEntityUpdateDTO.getId());
            orderByDesc("order_index");
            last("limit 1");
        }});
        SysBus sysBus = sysBusMapper.selectById(sysBusEntityUpdateDTO.getBus_id());
        if (sysBus == null) {
            throw new BusException("业务模型不存在");
        }
        //更新存储模型表
        SysBusEntity sysBusEntity = sysBusEntityConvert.updateDtoToEntity(sysBusEntityUpdateDTO);
        this.updateById(sysBusEntity);
        List<SysBusEntityFieldUpdateDTO> fieldList = sysBusEntityUpdateDTO.getFieldList();

        //过滤需要新增的字段
        List<SysBusEntityFieldUpdateDTO> add_fieldList = fieldList.stream().filter(SysBusEntityFieldUpdateDTO::getF_isAdd).collect(Collectors.toList());
        int index = 1;
        for (SysBusEntityFieldUpdateDTO item : add_fieldList) {
            //检查是否系统字段
            if (SysBusEntityCommon.exclude.contains(item.getF_name())) {
                throw new BusException("字段名不能是" + SysBusEntityCommon.exclude.toString());
            }
            //检查是否重复
            List<SysBusEntityField> sysBusEntityFields = sysBusEntityFieldMapper.selectList(new QueryWrapper<>() {{
                eq("entity_id", sysBusEntity.getId());
                eq("f_name", item.getF_name());
            }});
            if (sysBusEntityFields.size() > 0) {
                throw new BusException(StrUtil.format("字段({}-{})已经存在请修改名字", item.getF_title(), item.getF_name()));
            }
            try {
                //准备数据 使用context
                Context context = new Context();
                //添加基本类型
                context.setVariable("busName", sysBus.getBus_name().replaceAll("-", "_"));
                context.setVariable("table", sysBusEntity);
                context.setVariable("field", item);
                String dir = "add_field";
                String out = SysBusEntityCommon.getSqlTemplate(context, db, dir);

                dbUtilsBySession.excuteSql(out, getSqlSessionFactory().openSession());
                //插入到数据库字段表中
                SysBusEntityField sysBusEntityField = sysBusEntityFieldConvert.updateDtoToEntity(item);
                sysBusEntityField.setOrder_index(last_field.getOrder_index() + index);
                sysBusEntityField.setEntity_id(sysBusEntity.getId());
                sysBusEntityFieldMapper.insert(sysBusEntityField);
            } catch (Exception e) {
                log.error("字段添加失败", e);
                throw new BusException("字段添加失败");
            }
        }

        //过滤要删除的字段
        List<SysBusEntityFieldUpdateDTO> del_fieldList = fieldList.stream().filter(SysBusEntityFieldUpdateDTO::getF_isDel).collect(Collectors.toList());
        for (SysBusEntityFieldUpdateDTO item : del_fieldList) {
            try {
                //准备数据 使用context
                Context context = new Context();
                //添加基本类型
                context.setVariable("busName", sysBus.getBus_name().replaceAll("-", "_"));
                context.setVariable("table", sysBusEntity);
                context.setVariable("field", item);
                String dir = "del_field";
                String out = SysBusEntityCommon.getSqlTemplate(context, db, dir);

                this.getSqlSessionFactory().openSession();
                dbUtilsBySession.excuteSql(out, this.getSqlSessionFactory().openSession());
                //插入到数据库字段表中
                sysBusEntityFieldMapper.deleteById(item.getId());
            } catch (Exception e) {
                log.error("字段添加失败", e);
                throw new BusException("字段添加失败");
            }
        }

        //过滤要修改的字段
        List<SysBusEntityFieldUpdateDTO> update_fieldList = fieldList.stream().filter(item -> !item.getF_isAdd() && !item.getF_isDel() && StrUtil.isNotBlank(item.getId())).collect(Collectors.toList());
        for (SysBusEntityFieldUpdateDTO item : update_fieldList) {
            try {
                //准备数据 使用context
                Context context = new Context();
                //添加基本类型
                context.setVariable("busName", sysBus.getBus_name().replaceAll("-", "_"));
                context.setVariable("table", sysBusEntity);
                context.setVariable("field", item);
                String dir = "update_field";
                String out = SysBusEntityCommon.getSqlTemplate(context, db, dir);

                dbUtilsBySession.excuteSql(out, getSqlSessionFactory().openSession());
                //插入到数据库字段表中
                SysBusEntityField sysBusEntityField = sysBusEntityFieldConvert.updateDtoToEntity(item);
                sysBusEntityFieldMapper.updateById(sysBusEntityField);
            } catch (Exception e) {
                log.error("字段添加失败", e);
                throw new BusException("字段添加失败");
            }
        }

        try {
            //修改表描述
            Context context_table = new Context();
            context_table.setVariable("busName", sysBus.getBus_name().replaceAll("-", "_"));
            context_table.setVariable("table", sysBusEntity);
            String update_table_sql = SysBusEntityCommon.getSqlTemplate(context_table, db, "update_table");
            dbUtilsBySession.excuteSql(update_table_sql, this.getSqlSessionFactory().openSession());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteEntity(List<String> ids) throws BusException {
        for (String id : ids) {
            SysBusEntity sysBusEntity = getById(id);
            //查询业务模型
            SysBus sysBus = sysBusMapper.selectById(sysBusEntity.getBus_id());
            //删除存储数据
            this.removeById(id);
            try {
                //删除存储实体表
                Context context_table = new Context();
                context_table.setVariable("busName", sysBus.getBus_name().replaceAll("-", "_"));
                context_table.setVariable("table", sysBusEntity);
                String update_table_sql = SysBusEntityCommon.getSqlTemplate(context_table, db, "drop_table");
                dbUtilsBySession.excuteSql(update_table_sql, this.getSqlSessionFactory().openSession());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            //删除字段
            sysBusEntityFieldMapper.delete(new QueryWrapper<SysBusEntityField>().eq("entity_id", id));
        }
    }

    public static String removeBlankLines(String input) {
        Pattern pattern = Pattern.compile("^\\s*$\r?\n", Pattern.MULTILINE);
        Matcher matcher = pattern.matcher(input);
        return matcher.replaceAll("");
    }
}
